package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.constants.WemediaConstants;
import com.heima.constants.WmNewsConstants;
import com.heima.user.model.common.dtos.PageResponseResult;
import com.heima.user.model.common.dtos.ResponseResult;
import com.heima.user.model.common.enums.AppHttpCodeEnum;
import com.heima.user.utils.common.WmThreadLocalUtil;
import com.heima.wemedia.dtos.WmNewsDto;
import com.heima.wemedia.dtos.WmNewsPageReqDto;
import com.heima.wemedia.mapper.WmMaterialMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmNewsMaterialMapper;
import com.heima.wemedia.pojos.WmMaterial;
import com.heima.wemedia.pojos.WmNews;
import com.heima.wemedia.pojos.WmNewsMaterial;
import com.heima.wemedia.service.WmNewsMaterialService;
import com.heima.wemedia.service.WmNewsScanService;
import com.heima.wemedia.service.WmNewsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    @Autowired
    private WmNewsMapper wmNewsMapper;

    @Autowired
    private WmNewsMaterialMapper newsMaterialMapper;

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    @Autowired
    private WmNewsMaterialService wmNewsMaterialService;

    @Autowired
    private  WmNewsScanService wmNewsScanService;

    @Autowired
    private KafkaTemplate<String,String> kafkaTemplate;



    @Override
    public ResponseResult submit(WmNewsDto dto) {
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //获取图片地址
        List<String> imgesUrl = getContentImgesUrl(dto.getContent());
        //保存文章
        WmNews wmNews = saveWmNews(dto, imgesUrl);
        //关联正文图片和素材的关系
        saveNewsMaterial(wmNews.getId(), imgesUrl, WmNews.Status.NORMAL.getCode());
        //关联封面图片和素材的关系
        String images = wmNews.getImages();
        //如果有封面图片，则关联
        if (!StringUtils.isEmpty(images)){
            String[] Imgs = StringUtils.commaDelimitedListToStringArray(images);
            saveNewsMaterial(wmNews.getId(), Arrays.asList(Imgs), WemediaConstants.WM_COVER_REFERENCE);
        }

        //判断是否为草稿
        if (dto.getStatus() == WmNews.Status.NORMAL.getCode()){
            log.info("保存为草稿");
            wmNewsMapper.updateById(wmNews);
        }

        //审核文章
        wmNewsScanService.submit(wmNews);
        return ResponseResult.okResult(null);
    }


    /**
     * 关联文章和素材的关系
     * @param id
     * @param imgesUrl
     * @param type
     */
    private void saveNewsMaterial(Integer id, List<String> imgesUrl, Short type) {
        //如果没有图片，则不关联
        if (CollectionUtils.isEmpty(imgesUrl)) {
            return;
        }
        //通过URL获取素材id
        LambdaQueryWrapper<WmMaterial> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(WmMaterial::getUrl, imgesUrl);
        queryWrapper.eq(WmMaterial::getUserId, WmThreadLocalUtil.getUser().getId());

        //查询素材id
        List<WmMaterial> wmMaterials = wmMaterialMapper.selectList(queryWrapper);
        //获取素材id
        List<Integer> list = wmMaterials.stream().map((WmMaterial::getId)).collect(Collectors.toList());
        //批量关联
        if (!CollectionUtils.isEmpty(list)) {
            List<WmNewsMaterial> wmNewsMaterials = new ArrayList<>();
            for (Integer materialId : list) {
                WmNewsMaterial wmNewsMaterial = new WmNewsMaterial();
                wmNewsMaterial.setMaterialId(materialId);
                wmNewsMaterial.setNewsId(id);
                wmNewsMaterial.setType(type);
                wmNewsMaterials.add(wmNewsMaterial);
            }
            //批量保存
            wmNewsMaterialService.saveBatch(wmNewsMaterials);
        }
}

    /**
     * 保存文章
     *
     * @param dto
     * @param imgesUrl
     * @return
     */
    private WmNews saveWmNews(WmNewsDto dto, List<String> imgesUrl) {
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto, wmNews);
        //根据规则获取封面图片
        getImges(dto, imgesUrl, wmNews);

        wmNews.setUserId(WmThreadLocalUtil.getUser().getId());
        wmNews.setCreatedTime(new Date());
        wmNews.setSubmitedTime(new Date());

        //新增
        if (dto.getId() == null) {
            save(wmNews);
        } else {
            //删除关联关系表
            LambdaQueryWrapper<WmNewsMaterial> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(WmNewsMaterial::getNewsId, dto.getId());
            newsMaterialMapper.delete(queryWrapper);
            //修改
            updateById(wmNews);
        }

        return wmNews;
    }

    /**
     * 获取封面图片
     * 如果内容图片大于等于3  则是多图，截图3张图片作为封面
     * 如果内容图片大于等于1&&小于3  则是单图，截图1张图片作为封面
     * 如果内容没有图片，则是无图
     * @param dto
     * @param imgesUrl
     * @param wmNews
     */
    private void getImges(WmNewsDto dto, List<String> imgesUrl, WmNews wmNews) {
        //封面图片
        List<String> imges;
        //图片为自动,从文章中获取
        if (dto.getType().equals(WemediaConstants.WM_NEWS_TYPE_AUTO) ) {
            int size = imgesUrl.size();
            if (size >= 3) {
                wmNews.setType(WemediaConstants.WM_NEWS_MANY_IMAGE);
                imges = imgesUrl.stream().limit(3).collect(Collectors.toList());
                wmNews.setImages(StringUtils.collectionToCommaDelimitedString(imges));
            } else if (size >= 1) {
                wmNews.setType(WemediaConstants.WM_NEWS_SINGLE_IMAGE);
                imges = imgesUrl.stream().limit(1).collect(Collectors.toList());
                wmNews.setImages(StringUtils.collectionToCommaDelimitedString(imges));
            } else {
                wmNews.setType(WemediaConstants.WM_NEWS_NONE_IMAGE);
            }
        }

    }


    /**
     * 获取文章内容中的图片
     *
     * @param content
     * @return
     */
    private List<String> getContentImgesUrl(String content) {
        List<String> imgesUrl = new ArrayList<>();
        List<Map> mapList = JSONArray.parseArray(content, Map.class);
        for (Map map : mapList) {
            if ("image".equals(map.get("type"))) {
                imgesUrl.add((String) map.get("value"));
            }
        }
        return imgesUrl;
    }

    @Override
    public ResponseResult listAll(WmNewsPageReqDto dto) {
        //校验参数
        dto.checkParam();

        dto.setSize(12);
        Page<WmNews> page = new Page<>(dto.getPage(), dto.getSize());
        LambdaQueryWrapper<WmNews> queryWrapper = new LambdaQueryWrapper<>();
        //状态
        if (dto.getStatus() != null){
            queryWrapper.eq(WmNews::getStatus, dto.getStatus());
        }
        //频道
        if (dto.getChannelId() != null){
            queryWrapper.eq(WmNews::getChannelId, dto.getChannelId());
        }
        //关键字
        if (!StringUtils.isEmpty(dto.getKeyword())){
            queryWrapper.like(WmNews::getTitle, dto.getKeyword());
        }
        //时间范围
        if (dto.getBeginPubDate() != null && dto.getEndPubDate() != null){
            queryWrapper.between(WmNews::getPublishTime, dto.getBeginPubDate(), dto.getEndPubDate()+"23:59:59");
        }
        //排序
        queryWrapper.orderByDesc(WmNews::getPublishTime);

        //查询当前用户的文章
        queryWrapper.eq(WmNews::getUserId, WmThreadLocalUtil.getUser().getId());
        page = page(page, queryWrapper);

        PageResponseResult result = new PageResponseResult(dto.getPage(), dto.getSize(), Math.toIntExact(page.getTotal()));
        result.setData(page.getRecords());


        return result;
    }


    /**
     * 文章上下架
     * @param dto
     * @return
     */
    @Override
    public ResponseResult downOrUp(WmNewsDto dto) {
        //根据id查询文章
        LambdaQueryWrapper<WmNews> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(WmNews::getId, dto.getId());

        WmNews wmNews = wmNewsMapper.selectOne(queryWrapper);

        //修改文章Enable
        wmNews.setEnable(dto.getEnable());

        //文章是否存在
        if (StringUtils.isEmpty(wmNews)){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "文章不存在");
        }
        //判断文章是否是已发布
        if (!wmNews.getStatus().equals(WmNews.Status.PUBLISHED.getCode())){
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_PUBLISH_ERROR,"未发布");
        }

        wmNewsMapper.updateById(wmNews);


        kafkaTemplate.send(WmNewsConstants.WM_NEWS_TOPIC, JSON.toJSONString(wmNews));
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }
}
